"""
Settings manager for PDF Splitter application.
"""

import os
import json
from pathlib import Path
from typing import Dict, Any, Optional
from dataclasses import dataclass, asdict
import logging


@dataclass
class SplitSettings:
    """Settings for PDF split operations."""
    # Last used split mode
    split_mode: int = 0  # 0=range, 1=pages, 2=bookmark, 3=size

    # Split parameters
    page_ranges: str = ""
    pages_per_file: int = 10
    bookmark_level: int = 1
    max_size_mb: float = 10.0

    # Output settings
    output_directory: str = ""
    filename_template: str = "{original_name}_{part}"
    preserve_metadata: bool = True

    # Window settings
    window_width: int = 600
    window_height: int = 700

    # UI settings
    language: str = ""  # Language code (e.g., 'en_US', 'zh_CN')

    # Other preferences
    last_opened_files: list = None

    def __post_init__(self):
        if self.last_opened_files is None:
            self.last_opened_files = []


class SettingsManager:
    """Manages application settings persistence."""

    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.settings_file = Path.home() / ".pdf_splitter" / "settings.json"
        self.settings_dir = self.settings_file.parent
        self._settings: SplitSettings = SplitSettings()

        # Ensure settings directory exists
        self.settings_dir.mkdir(parents=True, exist_ok=True)

        # Load existing settings
        self.load_settings()

    def load_settings(self) -> None:
        """Load settings from file."""
        try:
            if self.settings_file.exists():
                with open(self.settings_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    # Convert dict to dataclass
                    self._settings = SplitSettings(**data)
                self.logger.info(f"Settings loaded from {self.settings_file}")
            else:
                self.logger.info("Settings file not found, using defaults")
        except Exception as e:
            self.logger.error(f"Failed to load settings: {e}")
            self._settings = SplitSettings()

    def save_settings(self) -> None:
        """Save settings to file."""
        try:
            # Convert dataclass to dict first
            settings_dict = asdict(self._settings)

            # Write to temporary file first
            temp_file = self.settings_file.with_suffix('.json.tmp')
            with open(temp_file, 'w', encoding='utf-8') as f:
                json.dump(settings_dict, f, indent=2, ensure_ascii=False)

            # Create a backup of current settings if it exists
            if self.settings_file.exists():
                backup_file = self.settings_file.with_suffix('.json.bak')
                try:
                    # Remove existing backup file if it exists
                    if backup_file.exists():
                        backup_file.unlink()
                    # Move current settings to backup
                    self.settings_file.rename(backup_file)
                except Exception as backup_error:
                    self.logger.warning(f"Failed to create backup file: {backup_error}")

            # Move temp file to actual settings file
            temp_file.replace(self.settings_file)

            self.logger.info(f"Settings saved to {self.settings_file}")

        except Exception as e:
            self.logger.error(f"Failed to save settings: {e}")
            # Clean up temp file if it exists
            try:
                if 'temp_file' in locals() and temp_file.exists():
                    temp_file.unlink()
            except:
                pass

    def get_settings(self) -> SplitSettings:
        """Get current settings."""
        return self._settings

    def update_settings(self, **kwargs) -> None:
        """Update specific settings."""
        for key, value in kwargs.items():
            if hasattr(self._settings, key):
                setattr(self._settings, key, value)
                self.logger.debug(f"Updated setting {key} = {value}")
            else:
                self.logger.warning(f"Unknown setting key: {key}")

    def add_recent_file(self, file_path: str) -> None:
        """Add a file to recent files list."""
        if not file_path:
            return

        # Convert to path and normalize
        file_path = str(Path(file_path).resolve())

        # Get current list
        recent_files = self._settings.last_opened_files.copy()

        # Remove if already exists
        if file_path in recent_files:
            recent_files.remove(file_path)

        # Add to beginning
        recent_files.insert(0, file_path)

        # Keep only last 10 files
        recent_files = recent_files[:10]

        # Update and save
        self._settings.last_opened_files = recent_files
        self.save_settings()

    def get_recent_files(self) -> list:
        """Get list of recent files."""
        return self._settings.last_opened_files.copy()

    def clear_recent_files(self) -> None:
        """Clear recent files list."""
        self._settings.last_opened_files = []
        self.save_settings()

    def save_window_geometry(self, width: int, height: int) -> None:
        """Save window geometry."""
        self._settings.window_width = width
        self._settings.window_height = height
        self.save_settings()

    def get_window_geometry(self) -> tuple:
        """Get saved window geometry."""
        return self._settings.window_width, self._settings.window_height


# Global settings instance
_settings_manager: Optional[SettingsManager] = None


def get_settings_manager() -> SettingsManager:
    """Get the global settings manager instance."""
    global _settings_manager
    if _settings_manager is None:
        _settings_manager = SettingsManager()
    return _settings_manager